import { Asset, ImageAsset, Prefab, SpriteFrame, Material, builtinResMgr } from "cc";
import { Singleton } from "../framework/base/Singleton";
import { ResLoader } from "../framework/ResLoader";
export enum EPath {
    mask = 'common/mask',
    hpbar = 'common/hpbar',
    shadow = 'common/shadow',
}

/** 材质类型 */
export enum EMaterialType {
    /** 全屏危险效果材质 */
    dangerMaterial = 'dangerMaterial',
    /** 自定义实体材质 */
    entityMaterial = 'entityMaterial',
    /** 马赛克 */
    mosaicmaterial = 'mosaicmaterial',
}

/** 资源管理 */
export default class ResManager extends Singleton {

    static get Ins() {
        return super.GetInstance<ResManager>()
    }

    private aniSpriteFrameMap: Map<any, SpriteFrame[]> = new Map()
    private spriteFrameMap: Map<any, SpriteFrame> = new Map()
    private prefabMap: Map<string, Prefab> = new Map()
    private materialMap: Map<string | EMaterialType, Material> = new Map()

    private loadRes<T extends Asset>(path: string, type: new (...args: any[]) => T) {
        return new Promise<T>((resolve, reject) => {
            ResLoader.Ins.load(path, type, (e: Error, a: T) => {
                if (e) {
                    resolve(null)
                    return
                }
                resolve(a)
            })
        })
    }

    private loadDir<T extends Asset>(path: string, type: new (...args: any[]) => T): Promise<T[]> {
        return new Promise((resolve, reject) => {
            ResLoader.Ins.loadDir(path, type, (e: Error, a: T[]) => {
                if (e) {
                    resolve([])
                    return
                }
                resolve(a)
            })
        })
    }

    /** 获取帧动画图片数组 */
    getAniSpriteFrames(entityType: string, stateType: number): Promise<SpriteFrame[]> {

        let path: string = 'entity/' + entityType + '/' + stateType
        return new Promise(async (resolve) => {
            if (this.aniSpriteFrameMap.has(path)) {
                resolve(this.aniSpriteFrameMap.get(path))
            } else {
                const sfArr = await this.loadDir(path, SpriteFrame)
                this.aniSpriteFrameMap.set(path, sfArr)
                /** todo:设置像素风 */
                for (const sf of sfArr) {
                    sf.texture.setFilters(0, 0)
                }
                resolve(sfArr)
            }
        })
    }

    /** 获取图片 */
    getSpriteFrame(name: string, folder: string): Promise<SpriteFrame> {
        let path: string = folder + '/' + name
        return new Promise(async (resolve) => {
            if (this.spriteFrameMap.has(path)) {
                resolve(this.spriteFrameMap.get(path))
            } else {
                const ia = await this.loadRes(path, ImageAsset)
                const sf = SpriteFrame.createWithImage(ia)
                this.spriteFrameMap.set(path, sf)
                resolve(sf)
            }
        })
    }

    /** 预加载材质 */
    async preLoadMaterial() {
        const materials = await this.loadDir('material', Material)
        for (const material of materials) {
            this.materialMap.set(material.name, material)
        }
    }

    /** 预加载通用预制体 */
    async preLoadCommon() {
        for (const key in EPath) {
            const path = EPath[key]
            const prefab = await this.loadRes(path, Prefab)
            this.prefabMap.set(path, prefab)
        }
    }

    /** 获取指定类型材质 */
    getMaterialByType(type: EMaterialType): Material {
        if (this.materialMap.has(type)) {
            return this.materialMap.get(type)
        }
        return builtinResMgr.get('ui-sprite-material')
    }

    /** 通过路径获取预制体 */
    getPrefabByPath(path: EPath) {
        return this.prefabMap.get(path)
    }

    // /** 设置精灵 */
    // setSpriteByRes(node: Node, url: string) {
    //     ResLoader.Ins.load(url as any, ImageAsset, (e: Error, ia: ImageAsset) => {
    //         if (e) {
    //             Logger.logBusiness('错误的 icon url:' + url)
    //             return
    //         }
    //         const sf = SpriteFrame.createWithImage(ia)
    //         node.uiSprite.spriteFrame = sf
    //     })
    // }
}